package service

import (
	"context"
	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	v13 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/intstr"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/log"
	appv1beta1 "taptap.com/app/api/v1beta1"
)

func ReconcileService(ctx context.Context, c client.Client, req ctrl.Request, app *appv1beta1.App) error {
	if len(app.Spec.Ports) == 0 {
		return nil
	}

	logger := log.FromContext(ctx)
	service := &v1.Service{}
	err := c.Get(ctx, req.NamespacedName, service)
	e, okay := err.(*errors.StatusError)
	if err != nil && (!okay || e.ErrStatus.Code != 404) {
		return err
	}

	{
		service.Name = app.Name
		service.Namespace = app.Namespace
		service.OwnerReferences = []v13.OwnerReference{
			{
				APIVersion: app.APIVersion,
				Kind:       app.Kind,
				Name:       app.Name,
				UID:        app.UID,
			},
		}
		service.Spec.Selector = app.Spec.Selector
		service.Spec.Ports = make([]v1.ServicePort, 0)
		for _, port := range app.Spec.Ports {
			service.Spec.Ports = append(service.Spec.Ports, v1.ServicePort{
				Name:       port.Name,
				Port:       port.ServicePort,
				TargetPort: intstr.FromInt(port.ContainerPort),
			})
		}
	}

	if e != nil && e.ErrStatus.Code == 404 {
		err = c.Create(ctx, service)
		if err != nil {
			logger.Error(err, "create service failed")
			return err
		}
		return nil
	}

	err = c.Update(ctx, service)
	if err != nil {
		logger.Error(err, "update service failed")
		return err
	}

	return nil
}
